/*
 * @Description:API
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2022-12-16 21:08:12
 * @LastEditors: zss
 * @LastEditTime: 2024-10-16 20:16:43
 */
import { axios, ifs, T_editor, ts, Tsrv } from '../config';
import { T_bgdFilter } from './filter';

export class T_bgdAPI extends T_bgdFilter {
  private cancelAxios: any;

  protected Teditor: T_editor;

  // 已被其它人锁定 key =  _sys_edit_lock.f_code
  public editLocked: Set<string> = new Set();

  constructor(obj: any) {
    super(obj);
    this.cancelAxios = null;
  }

  public loadFilterList(
    field
  ): Promise<
    Array<{
      field: string;
      value: any;
      virtualField: string;
      virtualValue: any;
    }>
  > {
    const gpfd: ts.T_GPFD = new ts.T_GPFD();
    gpfd.setLang(this.oBaseGrid.$i18n.locale || 'en-US');
    gpfd.setGlobalSerach(this.globalSearchText).setFunName(this.funName);
    gpfd.setFilter(this.getFilter()).setSort(this.getSortArr());
    gpfd.setDbType(this.dbType).setFunName(this.funName);
    gpfd.setTableName(this.tableName);
    const fieldName: string =
      field.indexOf('|') > -1 ? field.split('|')[1] : field;
    gpfd.setAgreedFields(fieldName);
    gpfd.setIsDistinct(true);
    const m2oField =
      this.m2oList.find(ele => ele.field === fieldName)?.m2oField || '';
    const slcField =
      this.slcList.find(ele => ele.field === fieldName)?.slcField || '';

    return new Promise((resolve, reject) => {
      Tsrv.getData<any, ifs.I_GPFD>(gpfd).then(r => {
        const [b, res, rows, msg] = r;
        !b && this.oBaseGrid.$msg(msg);
        const filterRow: Array<{
          field: string;
          value: any;
          virtualField: string;
          virtualValue: any;
        }> = [];
        rows.forEach(obj => {
          const value: any = obj[fieldName] || null;
          let virtualValue: any = null;
          let virtualField: string = '';
          if (m2oField) {
            virtualValue = obj[m2oField] ? obj[m2oField] : '';
            virtualField = m2oField;
          } else if (slcField) {
            virtualValue = obj[slcField] ? obj[slcField] : '';
            virtualField = slcField;
          }
          filterRow.push({
            field: fieldName,
            value,
            virtualField,
            virtualValue
          });
        });
        resolve(filterRow);
      });
    });
  }

  public loadTableData(): Promise<boolean> {
    const oBaseGrid = this.oBaseGrid;
    return new Promise((resolve, reject) => {
      if (!Tsrv.utils.isEmpty(this.tableName)) {
        // 当前不可编辑
        oBaseGrid.setToolbarStatus('edit', 'value', false);
        this.grid.clearEdit();
        const pageSize = oBaseGrid.pagerConfig
          ? oBaseGrid.tablePage.pageSize
          : 1000;
        const pageNo = oBaseGrid.pagerConfig
          ? oBaseGrid.tablePage.currentPage
          : 1;
        const gpd = new ts.T_getPartDataArg();
        gpd
          .setFunName(this.tableName)
          .setLang(oBaseGrid.$i18n.locale || 'en-US');
        gpd.setPage(pageNo, pageSize).setDbType(this.dbType);
        gpd.setGlobalSearch(this.globalSearchText);
        gpd.setFilter(this.getFilter());
        // this.sortArr.length > 0 && gpd.setSort(this.sortArr as ifs.I_sort[]);
        gpd.setSort(this.getSortArr());
        typeof this.cancelAxios === 'function' && this.cancelAxios();
        gpd.setCancel(
          new axios.CancelToken(c => {
            this.cancelAxios = c;
          })
        );
        // 正在加载
        oBaseGrid.loading = true;
        // 先处理 this.dataSource === 'table' 其它的再评估
        Tsrv.getData<any, ifs.I_getPartDataArg>(gpd)
          .then(([b, res, rows, msg]) => {
            if (!b) {
              msg && oBaseGrid.$msg(msg);
              resolve(false);
            }
            // 当前设置不可编辑
            oBaseGrid.setModify(false);
            // 当前未在加载
            oBaseGrid.loading = false;

            oBaseGrid.needSave = false;
            // 移除所有选中状态
            this.grid.clearCheckboxRow();
            // 更新选中状态
            oBaseGrid.checkboxChange(null);
            // 发送获取数据条数的事件
            oBaseGrid.loadDataInfo({
              funName: this.funName,
              total: res.data.total
            });
            // 如果行数 > 0 则设置第一行选中
            if (res.data.total > 0) {
              oBaseGrid.setToolbarStatus('edit', 'isDisable', false);
              let rowIdx = this.currSelectRowIdx;
              if (isNaN(rowIdx) || rows.length < rowIdx) {
                rowIdx = 0;
              } else if (rowIdx === -1) {
                rowIdx = rows.length - 1;
              }
              this.grid.setCurrentRow(rows[rowIdx]);
              oBaseGrid.setCurrentRow(rows[rowIdx], 0);
              oBaseGrid.storedSelection.forEach(item => {
                const find = Tsrv.utils.find(rows, el => el.id === item.id);
                if (find) {
                  this.grid.setCheckboxRow([find], true);
                }
              });
            } else {
              oBaseGrid.setToolbarStatus('edit', 'isDisable', true);
              oBaseGrid.messageEmit('search', []);
            }
            // // 设置表尾
            // this.footerData = data.footer || {};
            // this.isShowFooter = !Tsrv.utils.isEmpty(this.footerData);
            // oBaseGrid.footerData = res.data.footer || {};
            // oBaseGrid.isShowFooter = !Tsrv.utils.isEmpty(oBaseGrid.footerData);

            // 如果开启分页，设置总数
            if (oBaseGrid.pagerConfig) {
              oBaseGrid.pagerConfig.total = res.data.total;
            }
            // 设置起始Index
            oBaseGrid.seqStartIndex = pageSize * (pageNo - 1);

            // 设置表数据
            oBaseGrid.cloudData = Tsrv.utils.clone(rows, true);
            oBaseGrid.localData = rows;
            // 更新排序状态
            setTimeout(() => {
              this.setSortAndFilterActive();
              oBaseGrid.updateSaveBtnStatus();
            }, 0);
            resolve(true);
          })
          .catch(() => {
            oBaseGrid.loading = false;
          });
      }
    });
  }

  public loadEditLock(): Promise<boolean> {
    const oBaseGrid = this.oBaseGrid;
    this.editLocked.clear();
    oBaseGrid.isLoadEditLock = false;
    return new Promise((resolve, reject) => {
      // 正在加载
      oBaseGrid.loading = true;
      const gpd = new ts.T_getPartDataArg();
      gpd
        .setFunName(Tsrv.globalVar.funName.EDIT_LOCK)
        .setLang(oBaseGrid.$i18n.locale || 'en-US');
      gpd.setDbType(Tsrv.globalVar.dbType.MYSQL);
      gpd.setPage(1, 99999);
      gpd.setFilter({
        $and: [
          { [Tsrv.globalVar.fieldName.funID]: { $eq: this.funID } },
          { end_time: { $gt: new Date().toLocaleString() } }
        ]
      });
      Tsrv.getData<any, ifs.I_getPartDataArg>(gpd)
        .then(([b, res, rows, msg]) => {
          oBaseGrid.loading = false;
          if (!b) {
            msg && oBaseGrid.$msg(msg);
            resolve(false);
          }
          // 如果行数 > 0 则设置第一行选中
          if (res.data.total > 0) {
            rows.forEach(el => {
              if (el['f_code']) {
                this.editLocked.add(el['f_code']);
              }
            });
          }
          resolve(true);
        })
        .catch(e => {
          // 正在加载
          oBaseGrid.loading = false;
          console.error(e);
        });
    });
  }

  // expExcle
  public exportMethod(opt) {
    const options = opt.options;
    const oBaseGrid = this.oBaseGrid;
    const fields = options.columns
      .map(el => el.property)
      .filter(el => el !== undefined);
    fields.forEach((field, idx) => {
      const slcID = opt.$table.getColumnByField(field)?.params?.source
        ?.selectionID;
      if (slcID) {
        fields[idx] = `slc|${field}|${slcID}`;
      }
    });
    const p = {
      fileName: options.filename,
      dbType: this.dbType,
      tableName: this.tableName,
      rule: {},
      funName: this.funName,
      fields,
      lang: oBaseGrid.$i18n.locale || 'en-US',
      globalSearch: this.globalSearchText,
      filter: this.getFilter(),
      sort: this.sortArr
    };
    const msg = this.oBaseGrid.$Message.loading({
      content: `${Tsrv.getI18nByValue('正在导出')}···`,
      duration: 0
    });
    Tsrv.expExcel(
      p.fileName,
      p.dbType,
      p.funName,
      p.lang,
      p.fields,
      p.filter,
      p.sort,
      p.globalSearch
    )
      .then(b => {
        // @ts-ignore
        msg();
        if (b) {
          oBaseGrid.$msg('200,FE,0');
        }
      })
      .catch(e => {
        throw new Error(e);
      });
  }

  // /**
  //  * 执行过程
  //  */
  // public doActions(action: string, params: any) {
  //   return new Promise((resolve, reject) => {
  //     params['spName'] = action;
  //     Tsrv.standardPostReq<ifs.I_setDataRes, any>(params, Tsrv.url.fun)
  //       .then(([res, err]) => {
  //         if (res.success) {
  //           resolve(true);
  //         } else {
  //           this.oBaseGrid.$msg(res.msg);
  //           reject();
  //         }
  //       })
  //       .catch(e => {
  //         this.oBaseGrid.$msg(e);
  //         console.error(e);
  //       });
  //   });
  // }

  /**
   * 批量操作
   */
  public batchCTD(changes: any) {
    const oBaseGrid = this.oBaseGrid;
    // 准备新增、删除和更新的容器，新增和删除直接转化得来
    return new Promise((resolve, reject) => {
      // 如果有更改
      if (
        !(
          changes.insertRecords.length === 0 &&
          changes.removeRecords.length === 0 &&
          changes.updateRecords.length === 0
        )
      ) {
        const actionsCfg = this.actionsCfg;
        // 暂时在此拦截，修改新格式ctd传参
        const ctd = new ts.T_ctdArg();
        ctd.setTableName(this.tableName).setDbType(this.dbType);
        ctd.setRule({} as ifs.I_rule);
        if (changes.insertRecords.length > 0) {
          // 2.0版本scope 改为一个bson表达过滤条件
          let scope = {};
          if (this.scope && this.scope?.field) {
            // scope = JSON.parse(`{"${this.scope.field}":${this.scope.value}}`);
            scope = { [`${this.scope.field}`]: this.scope.value };
          }
          const bDatas: ifs.I_baseData[] = [];
          changes.insertRecords.forEach(ele => {
            const bData = new ts.T_baseData();
            bData
              .setDataRule({} as ifs.I_rule)
              .setFileInfo({})
              .setRowData(...(ele as ifs.I_fv[]));
            bDatas.push(bData);
          });
          ctd.setInsRecDataMany(scope, ...bDatas);
          // 加入 ctd操作 前后事件
          // const syncParams = new ts.T_syncParams();
          const p = {
            funName: this.getFunName(),
            from: '',
            data: { insertRecords: changes.insertRecords },
            parentID: this.oBaseGrid.linkParent.rowID || 0
          };
          if (actionsCfg.beforeInsert) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'beforeInsert';
            syncParams
              .setApiName(actionsCfg.beforeInsert)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setInsRecBefSync([syncParams]);
          }
          if (actionsCfg.afterInsert) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'afterInsert';
            syncParams
              .setApiName(actionsCfg.afterInsert)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setInsRecAftSync([syncParams]);
          }
        }
        if (changes.removeRecords.length > 0) {
          const ids = `"${changes.removeRecords.join(`","`)}"`;
          const filter = JSON.parse(`{"id":{"$in":[${ids}]}}`);
          ctd.setDelRecData({} as ifs.I_rule, filter);
          // 加入 ctd操作 前后事件
          // const syncParams = new ts.T_syncParams();
          const p = {
            funName: this.getFunName(),
            from: '',
            data: { removeRecords: ids },
            parentID: this.oBaseGrid.linkParent.rowID || 0
          };
          if (actionsCfg.beforeDelete) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'beforeDelete';
            syncParams
              .setApiName(actionsCfg.beforeDelete)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setDelRecBefSync([syncParams]);
          }
          if (actionsCfg.afterDelete) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'afterDelete';
            syncParams
              .setApiName(actionsCfg.afterDelete)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setDelRecAftSync([syncParams]);
          }
        }
        if (changes.updateRecords.length > 0) {
          let filter: any = {};
          const ctdUpdDatas: ifs.I_ctdUpdData[] = [];
          changes.updateRecords.forEach(ele => {
            const ctdUpdData = new ts.T_ctdUpdData();
            ctdUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
            const rowData: ifs.I_fv[] = [];
            ele.forEach(item => {
              // 取出id作为过滤条件
              if (item?.field === 'id') {
                filter = { id: item?.value };
              } else {
                rowData.push(item);
              }
            });
            ctdUpdData.setFilter(filter);
            ctdUpdData.setRowData(...rowData);
            ctdUpdDatas.push(ctdUpdData);
          });
          ctd.setUpdRecDataMany(...ctdUpdDatas);
          // 加入 ctd操作 前后事件
          // const syncParams = new ts.T_syncParams();
          const updateRecords = [];
          changes.updateRecords.forEach(ele => {
            const rowData = {};
            ele.forEach(item => {
              rowData[item.field] = item.value;
            });
            updateRecords.push(rowData);
          });
          const p = {
            funName: this.getFunName(),
            from: '',
            data: updateRecords,
            parentID: this.oBaseGrid.linkParent.rowID || 0
          };
          if (actionsCfg.beforeEdit) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'beforeEdit';
            syncParams
              .setApiName(actionsCfg.beforeEdit)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setUpdRecBefSync([syncParams]);
          }
          if (actionsCfg.afterEdit) {
            const syncParams = new ts.T_syncParams();
            const _p = Tsrv.utils.clone(p, true);
            _p.from = 'afterEdit';
            syncParams
              .setApiName(actionsCfg.afterEdit)
              .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
              .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
              .setSyncData(_p);
            ctd.setUpdRecAftSync([syncParams]);
          }
        }

        Tsrv.batRows(ctd).then(resp => {
          const [b, res, msg] = resp;
          msg && oBaseGrid.$msg(msg);
          if (b) {
            oBaseGrid.needSave = false;
            // 保存成功后刷新
            if (changes.removeRecords.length === oBaseGrid.localData.length) {
              oBaseGrid.tablePage.currentPage > 1 &&
                oBaseGrid.tablePage.currentPage--;
            }
            this.loadTableData();
            oBaseGrid.editStatus = false;
            resolve(true);
          } else {
            reject();
          }
          oBaseGrid.loading = false;
        });
      } else {
        reject();
      }
    });
  }

  /**
   * 删除操作
   */
  public delCTD() {
    const oBaseGrid = this.oBaseGrid;
    return new Promise((resolve, reject) => {
      const removes = this.grid.getCheckboxRecords().map(el => {
        return el.id;
      });
      const delRec = new ts.T_ctdDelRec();
      delRec.setRule({} as ifs.I_rule);
      if (removes.length > 0) {
        const ids = `"${removes.join(`","`)}"`;
        const filter = JSON.parse(`{"id":{"$in":[${ids}]}}`);
        delRec.setFilter(filter);
      } else {
        reject();
      }
      // 加入 ctd操作 前后事件
      // const syncParams = new ts.T_syncParams();
      const p = {
        funName: this.getFunName(),
        from: '',
        data: { removeRecords: removes },
        parentID: this.oBaseGrid.linkParent.rowID || 0
      };
      if (this.actionsCfg.beforeDelete) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'beforeDelete';
        syncParams
          .setApiName(this.actionsCfg.beforeDelete)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
          .setSyncData(_p);
        delRec.setBefEvent(syncParams);
      }
      if (this.actionsCfg.afterDelete) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'afterDelete';
        syncParams
          .setApiName(this.actionsCfg.afterDelete)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo)
          .setSyncData(_p);
        delRec.setAftEvent(syncParams);
      }
      // 删除
      Tsrv.delRows(this.tableName, this.dbType, {} as ifs.I_rule, delRec).then(
        resp => {
          const [b, res, msg] = resp;
          if (b) {
            msg ? oBaseGrid.$msg(msg) : oBaseGrid.$msg('50002,FE,0,');
            oBaseGrid.loading = false;
            oBaseGrid.commitEvent('reload');
            resolve(true);
          } else {
            oBaseGrid.loading = false;
            msg ? oBaseGrid.$msg(msg) : oBaseGrid.$msg('-50002,FE,11,');
            reject();
          }
        }
      );
    });
  }

  /**
   * 加载数据advance search
   */
  public loadTableDataAdvq() {
    const oBaseGrid = this.oBaseGrid;
    this.editLocked.clear();
    return new Promise(resolve => {
      const params = oBaseGrid.advqParams === null ? '' : oBaseGrid.advqParams;
      const pageSize = oBaseGrid.pagerConfig
        ? oBaseGrid.tablePage.pageSize
        : 1000;
      const pageNo = oBaseGrid.pagerConfig
        ? oBaseGrid.tablePage.currentPage
        : 1;
      const pageConf = {
        pageNo,
        pageSize
      };
      params.pagination = pageConf;
      if (params && params !== '') {
        oBaseGrid.loading = true;
        Tsrv.httpReqV1
          .advq(params)
          .then((data: any) => {
            data = data.data;
            oBaseGrid.loading = false;
            if (data.success) {
              // page
              if (oBaseGrid.pagerConfig) {
                oBaseGrid.pagerConfig.total = data.data.total;
              }
              // seq
              oBaseGrid.seqStartIndex = pageSize * (pageNo - 1);
              oBaseGrid.localData = data.data.rows;
              this.grid.setCurrentRow(data.data.rows[0]);
              oBaseGrid.setCurrentRow(data.data.rows[0], 0);
              resolve(data.data.rows);
            } else {
              resolve(false);
            }
          })
          .catch(() => {
            oBaseGrid.loading = false;
          });
      } else {
        resolve(false);
      }
    });
  }

  public doEvent(
    action: string,
    params: any,
    serviceData: any = null,
    isShowMsg: boolean = true
  ) {
    return new Promise<boolean>((resove, reject) => {
      let goTo: boolean = true;
      for (const o of this.oBaseGrid._config.toolbar.addon) {
        if (
          o.title === params.title &&
          o?.singleSelChk === true &&
          this.grid.getCheckboxRecords().length > 1
        ) {
          this.oBaseGrid.$msg(Tsrv.getI18nByValue('只能选择一条数据'));
          resove(false);
          goTo = false;
          break;
        }
      }
      if (goTo) {
        Tsrv.doEvent(
          action,
          Tsrv.getFunInfo(this.mainFunName) as ifs.I_funInfo,
          () => params,
          isShowMsg
        )
          .then(r => {
            if (r.isErr()) {
              this.oBaseGrid.$msg(r.errmsg);
              resove(false);
            } else {
              const res = r.getReturnData('conf');
              if (Tsrv.utils.noValue(res)) {
                return;
              }
              if (res.res?.data?.openUrl && res.res.success) {
                Tsrv.reliablySendingBusEvent(
                  'OPEN_URL',
                  undefined,
                  undefined,
                  undefined,
                  res.res.data.openUrl
                );
              }
              // 0 存储过程  1 逻辑服务 2 规则库 3 web请求 4 系统策略
              if (res.apiType <= 2 || res.apiType === 4) {
                // this.oBaseGrid.$msg(res.res.msg);
                // 会话处理
                this.Teditor.interactionMsgHandle(
                  res.res.data?.request,
                  res.res.data?.data,
                  serviceData,
                  isShowMsg
                );
                // this.loadTableData();
              } else if (res.apiType === 3) {
                // 请求接口
                const p = {
                  funName: this.getFunName(),
                  from: 'WebRequest',
                  title: action,
                  data: {
                    req: res['data'],
                    res: res.res[0].data
                  },
                  // data: res.res[0].data.data,
                  parentID: this.oBaseGrid.linkParent.rowID || 0
                };
                this.doEvent(Tsrv.lexicon.globalVar.spName.webApiReq, p);
              }
              resove(true);
            }
          })
          .catch(err => {
            console.error(err);
            reject(false);
          });
      }
    });
  }
}
export interface I_bgdAPI extends T_bgdAPI {}
